/**
 * @file lv_port.c
 *
 */

#include "esp_log.h"
#include <stdint.h>

#define TAG "lvgl"
/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable
 * content*/
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "driver/gpio.h"
#include "lv_port.h"
#include <stdbool.h>

/*********************
 *      DEFINES
 *********************/
#ifndef MY_DISP_HOR_RES
#define MY_DISP_HOR_RES 280
#endif

#ifndef MY_DISP_VER_RES
#define MY_DISP_VER_RES 240
#endif

#define TP_RST_PIN 14

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void disp_init(void);
static void disp_flush(lv_display_t *disp, const lv_area_t *area,
                       lv_color_t *px_map);

static void touchpad_init(void);
static void touchpad_read(lv_indev_t *indev, lv_indev_data_t *data);
static bool touchpad_is_pressed(void);
static void touchpad_get_xy(int32_t *x, int32_t *y);

/**********************
 *  STATIC VARIABLES
 **********************/
lv_display_t *disp;
lv_indev_t *indev_touchpad;
/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_port_disp_init(void) {
  /*-------------------------
   * Initialize your display
   * -----------------------*/
  disp_init();

  /*------------------------------------
   * Create a display and set a flush_cb
   * -----------------------------------*/
  disp = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES);
  lv_display_set_flush_cb(disp, disp_flush);

  /* Example 2
   * Two buffers for partial rendering
   * In flush_cb DMA or similar hardware should be used to update the display in
   * the background.*/
  static lv_color_t buf_2_1[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10];
  static lv_color_t buf_2_2[MY_DISP_HOR_RES * MY_DISP_VER_RES / 10];
  lv_display_set_buffers(disp, buf_2_1, buf_2_2, sizeof(buf_2_1),
                         LV_DISPLAY_RENDER_MODE_PARTIAL);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
extern void lvgl_driver_init(void);
/*Initialize your display and the required peripherals.*/
static void disp_init(void) { /*You code here*/
  lvgl_driver_init();
}

volatile bool disp_flush_enabled = true;

/* Enable updating the screen (the flushing process) when disp_flush() is called
 * by LVGL
 */
void disp_enable_update(void) { disp_flush_enabled = true; }

/* Disable updating the screen (the flushing process) when disp_flush() is
 * called by LVGL
 */
void disp_disable_update(void) { disp_flush_enabled = false; }

/*Flush the content of the internal buffer the specific area on the display.
 *`px_map` contains the rendered image as raw pixel map and it should be copied
 *to `area` on the display. You can use DMA or any hardware acceleration to do
 *this operation in the background but 'lv_display_flush_ready()' has to be
 *called when it's finished.*/

extern void disp_driver_flush(lv_display_t *drv, const lv_area_t *area,
                              lv_color_t *color_map);
static void disp_flush(lv_display_t *disp_drv, const lv_area_t *area,
                       lv_color_t *px_map) {
  if (disp_flush_enabled) {
    /*The most simple case (but also the slowest) to put all pixels to the
     * screen one-by-one*/
    lv_draw_sw_rgb565_swap(px_map, lv_area_get_size(area));
    disp_driver_flush(disp_drv, area, px_map);
  }

  /*IMPORTANT!!!
   *Inform the graphics library that you are ready with the flushing*/
  lv_display_flush_ready(disp_drv);
}

void lv_port_indev_init(void) {
  /*------------------
   * Touchpad
   * -----------------*/

  /*Initialize your touchpad if you have*/
  touchpad_init();

  /*Register a touchpad input device*/
  indev_touchpad = lv_indev_create();
  lv_indev_set_type(indev_touchpad, LV_INDEV_TYPE_POINTER);
  lv_indev_set_read_cb(indev_touchpad, touchpad_read);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/*------------------
 * Touchpad
 * -----------------*/

/*Initialize your touchpad*/
static void touchpad_init(void) {

}

//extern bool touch_driver_read(lv_indev_t *indev_drv, lv_indev_data_t *data);
/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_t *indev_drv, lv_indev_data_t *data) {
  /*Save the pressed coordinates and the state*/
  // if (!gpio_get_level(TP_RST_PIN)) {
    //touch_driver_read(indev_drv, data);
  //}
}

#else /*Enable this file at the top*/

/*This dummy typedef exists purely to silence -Wpedantic.*/
typedef int keep_pedantic_happy;
#endif
